﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace TXK
{
    public abstract class ScoketDevBase : INotifyPropertyChanged
    {
        #region 属性
        /// <summary>
        /// 当前数据集合(VarName作为键名)
        /// </summary>
        public Dictionary<string, object> CurrentValueListByVarName { get; set; } = new();
        /// <summary>
        /// 当前数据集合(Address作为键名)
        /// </summary>
        public Dictionary<string, object> CurrentValueListByAddress { get; set; } = new();
        /// <summary>
		/// 计时器
		/// </summary>
		public Stopwatch sw = new Stopwatch();
        /// <summary>
        /// 定义一个信号源
        /// </summary>
        public CancellationTokenSource cts { get; set; } = new CancellationTokenSource();
        /// <summary>
        /// 是否是第一次连接,默认为true
        /// </summary>
        public bool FirstConnect { get; set; } = true;
        /// <summary>
        /// IP地址
        /// </summary>
        public string Ip { get; set; }
        /// <summary>
        /// 端口号
        /// </summary>
        public string Port { get; set; }
        /// <summary>
        /// 设备名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 设备描述
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 
        /// </summary>
       // public long CycleTime { get; set; }
        private long cycletime;

        public long CycleTime
        {
            get { return cycletime; }
            set { cycletime = value; OnPropertyChanged("CycleTime"); }
        }

        /// <summary>
        /// 报警事件
        /// </summary>
        public event AlarmEventHander AlarmEvent;
        #region 依赖属性
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string properName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(properName));
            }
        }
        #endregion
        private bool isConnected;
        /// <summary>
        /// 连接状态(网口)
        /// </summary>
        public bool IsConnected
        {
            get { return isConnected; }
            set { isConnected = value; OnPropertyChanged("IsConnected"); }
        }
        /// <summary>
        /// 断线后重连间隔时间，默认500毫秒,为0的话,会不停的重连
        /// </summary>
        public int ReConnectTime { get; set; } = 500;
        public int ErrorTimes { get; internal set; }
        public int MaxErrorTimes { get; internal set; }
        #endregion

        #region 方法
        public abstract void Start();
        /// <summary>
        /// 检测报警
        /// </summary>
        /// <param name="variable">待检测变量</param>
        /// <param name="val">当前值</param>
        public void CheckAlarm(VariableBase variable, string val)
        {
            if (variable.AlarmEnable)
            {
                if (variable.AlarmType == CommonBase.AlarmType.条件报警)//条件报警
                {
                    var result = 0f;
                    if (!float.TryParse(val, out result))
                    {
                        //throw new Exception("转化错误");
                        return;
                    }
                    if (variable.HiHiAlarmEnable)
                    {

                        var num = Helper.IsAlarm(result, variable.HiHiAlarmValue, variable.HiHiCacheValue, isPositive: true);
                        if (num != 0)
                        {
                            AlarmEvent(variable, new AlarmEventArgs
                            {
                                AlarmInfo = variable.HiHiAlarmNote,
                                CurrentValue = result.ToString(),
                                SetValue = variable.HiHiAlarmValue.ToString(),
                                IsACK = (num == 1)
                            });
                        }
                        variable.HiHiCacheValue = result;
                    }
                    if (variable.HighAlarmEnable)
                    {

                        var num2 = Helper.IsAlarm(result, variable.HighAlarmValue, variable.HighCacheValue, isPositive: true);
                        if (num2 != 0)
                        {
                            this.AlarmEvent(variable, new AlarmEventArgs
                            {
                                AlarmInfo = variable.HighAlarmNote,
                                CurrentValue = result.ToString(),
                                SetValue = variable.HighAlarmValue.ToString(),
                                IsACK = (num2 == 1)
                            });
                        }
                        variable.HighCacheValue = result;
                    }
                    if (variable.LoLoAlarmEnable)
                    {

                        var num3 = Helper.IsAlarm(result, variable.LoLoAlarmValue, variable.LoLoCacheValue, isPositive: false);
                        if (num3 != 0)
                        {
                            this.AlarmEvent(variable, new AlarmEventArgs
                            {
                                AlarmInfo = variable.LoLoAlarmNote,
                                CurrentValue = result.ToString(),
                                SetValue = variable.LoLoAlarmValue.ToString(),
                                IsACK = (num3 == 1)
                            });
                        }
                        variable.LoLoCacheValue = result;
                    }
                    if (variable.LowAlarmEnable)
                    {

                        var num4 = Helper.IsAlarm(result, variable.LowAlarmValue, variable.LowCacheValue, isPositive: false);
                        if (num4 != 0)
                        {
                            this.AlarmEvent(variable, new AlarmEventArgs
                            {
                                AlarmInfo = variable.LowAlarmNote,
                                CurrentValue = result.ToString(),
                                SetValue = variable.LowAlarmValue.ToString(),
                                IsACK = (num4 == 1)
                            });
                        }
                        variable.LowCacheValue = result;
                    }
                    return;
                }
                else//离散报警
                {
                    var flag = val.ToLower() == "1";
                    if (variable.DiscreteAlarmType == CommonBase.DiscreteAlarmType.上升沿报警)
                    {
                        var num5 = Helper.IsAlarm(flag ? 1f : 0f, 1f, variable.DiscreteRiseCacheValue ? 1f : 0f, isPositive: true);
                        if (num5 != 0)
                        {
                            this.AlarmEvent(variable, new AlarmEventArgs
                            {
                                AlarmInfo = variable.DiscreteAlarmNote,
                                CurrentValue = flag.ToString(),
                                SetValue = "True",
                                IsACK = (num5 == 1)
                            });
                        }
                        variable.DiscreteRiseCacheValue = flag;
                    }
                    else
                    {
                        var num6 = Helper.IsAlarm(flag ? 1f : 0f, 0f, variable.DiscreteFallCacheValue ? 1f : 0f, isPositive: false);
                        if (num6 != 0)
                        {
                            this.AlarmEvent(variable, new AlarmEventArgs
                            {
                                AlarmInfo = variable.DiscreteAlarmNote,
                                CurrentValue = flag.ToString(),
                                SetValue = "False",
                                IsACK = (num6 == 1)
                            });
                        }
                        variable.DiscreteFallCacheValue = flag;
                    }
                }

            }
        }
        #endregion
    }
    #region 报警委托和报警参数
    /// <summary>
    /// 报警事件参数
    /// </summary>
    public class AlarmEventArgs : EventArgs
    {
        /// <summary>
        /// 报警信息
        /// </summary>
        public string AlarmInfo { get; set; }

        /// <summary>
        /// 报警值
        /// </summary>
        public string CurrentValue { get; set; }

        /// <summary>
        /// 报警设定值
        /// </summary>
        public string SetValue { get; set; }

        /// <summary>
        /// 触发或消除
        /// </summary>
        public bool IsACK { get; set; }
    }
    /// <summary>
    /// 报警委托
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void AlarmEventHander(object sender, AlarmEventArgs e);
    #endregion
}
